package itsm.isperp.workflow.cmd;

import itsm.isperp.framework.core.context.ContextHolder;
import itsm.isperp.framework.data.dialect.DialectFactory;
import itsm.isperp.workflow.graph.Edge;
import itsm.isperp.workflow.graph.Graph;
import itsm.isperp.workflow.graph.Node;

import org.activiti.engine.impl.context.Context;
import org.activiti.engine.impl.interceptor.Command;
import org.activiti.engine.impl.interceptor.CommandContext;
import org.activiti.engine.impl.persistence.entity.TaskEntity;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.jdbc.core.JdbcTemplate;

/**
 * 
 * 
 * 
 * @author lizx
 * @date 2015-2-3
 * @since 1.0
 * 
 */
public class FindNearestUserTaskCmd implements Command<String> {

	private static Logger logger = LoggerFactory
			.getLogger(FindNearestUserTaskCmd.class);

	String taskId;

	public FindNearestUserTaskCmd(String taskId) {
		this.taskId = taskId;

	}

	@Override
	public String execute(CommandContext commandContext) {
		return findNearestUserTask();
	}

	public String findNearestUserTask() {
		TaskEntity taskEntity = Context.getCommandContext()
				.getTaskEntityManager().findTaskById(taskId);

		if (taskEntity == null) {
			logger.debug("cannot find task : {}", taskId);

			return null;
		}
		JdbcTemplate jdbcTemplate = ContextHolder
				.getSpringBean(JdbcTemplate.class);

		String sql = "SELECT task_id_ FROM ACT_HI_ACTINST WHERE act_type_='userTask' "

				+ " AND proc_inst_id_='"
				+ taskEntity.getProcessInstanceId()
				+ "' AND end_time_ IS NOT NULL ORDER BY end_time_ DESC";

		return jdbcTemplate.queryForObject(DialectFactory.getDialect()
				.getLimitString(sql), String.class);

	}

	public String findIncomingNode(Graph graph, Node node) {
		for (Edge edge : graph.getEdges()) {
			Node src = edge.getSrc();
			Node dest = edge.getDest();
			String srcType = src.getType();

			if (!dest.getId().equals(node.getId())) {
				continue;
			}

			if ("userTask".equals(srcType)) {
				return src.getId();
			} else if (srcType.endsWith("Gateway")) {
				return findIncomingNode(graph, src);
			} else {
				logger.info("cannot rollback, previous node is not userTask : "
						+ src.getId() + " " + srcType + "(" + src.getName()
						+ ")");

				return null;
			}
		}

		logger.info("cannot rollback, this : " + node.getId() + " "
				+ node.getType() + "(" + node.getName() + ")");

		return null;
	}
}
